Properly handle model changes in GtkTreeSelection: (#322569, Milosz
authorMatthias Clasen <mclasen@redhat.com>
Tue, 29 Nov 2005 19:34:15 +0000 (19:34 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Tue, 29 Nov 2005 19:34:15 +0000 (19:34 +0000)
2005-11-29  Matthias Clasen  <mclasen@redhat.com>

Properly handle model changes in GtkTreeSelection: (#322569,
Milosz Derezynski)

* gtk/gtktreeselection.c (gtk_tree_selection_selected_foreach):
Get a reference to the model, and stop the iteration if the model
of the treeview is changed on the way.

* gtk/gtktreeprivate.h:
* gtk/gtktreeselection.c (_gtk_tree_selection_emit_changed): New
private function to emit the GtkTreeSelection::changed signal.

* gtk/gtktreeview.c (gtk_tree_view_set_model): Call
_gtk_tree_selection_emit_changed() when the model changes.

ChangeLog
ChangeLog.pre-2-10
gtk/gtktreeprivate.h
gtk/gtktreeselection.c
gtk/gtktreeview.c

index f25ba7e561322f45ac965f1624ddef7ae5922bae..9c5196b6d4dc623d44a4e56f842b770362253474 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2005-11-29  Matthias Clasen  <mclasen@redhat.com>
+
+       Properly handle model changes in GtkTreeSelection: (#322569,
+       Milosz Derezynski)
+       
+       * gtk/gtktreeselection.c (gtk_tree_selection_selected_foreach): 
+       Get a reference to the model, and stop the iteration if the model
+       of the treeview is changed on the way.
+
+       * gtk/gtktreeprivate.h: 
+       * gtk/gtktreeselection.c (_gtk_tree_selection_emit_changed): New 
+       private function to emit the GtkTreeSelection::changed signal.
+
+       * gtk/gtktreeview.c (gtk_tree_view_set_model): Call 
+       _gtk_tree_selection_emit_changed() when the model changes.
+
 2005-11-28  Federico Mena Quintero  <federico@ximian.com>
 
        Fixes the critical warnings from bug #317999, thus fixing the bug
index f25ba7e561322f45ac965f1624ddef7ae5922bae..9c5196b6d4dc623d44a4e56f842b770362253474 100644 (file)
@@ -1,3 +1,19 @@
+2005-11-29  Matthias Clasen  <mclasen@redhat.com>
+
+       Properly handle model changes in GtkTreeSelection: (#322569,
+       Milosz Derezynski)
+       
+       * gtk/gtktreeselection.c (gtk_tree_selection_selected_foreach): 
+       Get a reference to the model, and stop the iteration if the model
+       of the treeview is changed on the way.
+
+       * gtk/gtktreeprivate.h: 
+       * gtk/gtktreeselection.c (_gtk_tree_selection_emit_changed): New 
+       private function to emit the GtkTreeSelection::changed signal.
+
+       * gtk/gtktreeview.c (gtk_tree_view_set_model): Call 
+       _gtk_tree_selection_emit_changed() when the model changes.
+
 2005-11-28  Federico Mena Quintero  <federico@ximian.com>
 
        Fixes the critical warnings from bug #317999, thus fixing the bug
index f91679b261abeb020abfd834d7ceaff80b1842c2..e4a33372473fbe01e07e5c484654f2af25c9025f 100644 (file)
@@ -312,6 +312,7 @@ void         _gtk_tree_selection_internal_select_node (GtkTreeSelection  *select
                                                       GtkTreePath       *path,
                                                        GtkTreeSelectMode  mode,
                                                       gboolean           override_browse_mode);
+void         _gtk_tree_selection_emit_changed         (GtkTreeSelection  *selection);
 gboolean     _gtk_tree_view_find_node                 (GtkTreeView       *tree_view,
                                                       GtkTreePath       *path,
                                                       GtkRBTree        **tree,
index 9bc15100a37abb39646313628ee8fe5376be3fd9..90a0dac1745200e0d6ba76f38a58e7e9632f8718 100644 (file)
@@ -614,8 +614,9 @@ gtk_tree_selection_selected_foreach (GtkTreeSelection            *selection,
   GtkRBTree *tree;
   GtkRBNode *node;
   GtkTreeIter iter;
+  GtkTreeModel *model;
 
-  guint inserted_id, deleted_id, reordered_id;
+  gulong inserted_id, deleted_id, reordered_id, changed_id;
   gboolean stop = FALSE;
 
   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
@@ -645,19 +646,22 @@ gtk_tree_selection_selected_foreach (GtkTreeSelection            *selection,
   while (node->left != tree->nil)
     node = node->left;
 
+  model = selection->tree_view->priv->model;
+  g_object_ref (model);
+
   /* connect to signals to monitor changes in treemodel */
-  inserted_id = g_signal_connect_swapped (selection->tree_view->priv->model,
-                                          "row_inserted",
+  inserted_id = g_signal_connect_swapped (model, "row_inserted",
                                          G_CALLBACK (model_changed),
                                          &stop);
-  deleted_id = g_signal_connect_swapped (selection->tree_view->priv->model,
-                                         "row_deleted",
+  deleted_id = g_signal_connect_swapped (model, "row_deleted",
                                         G_CALLBACK (model_changed),
                                         &stop);
-  reordered_id = g_signal_connect_swapped (selection->tree_view->priv->model,
-                                           "rows_reordered",
+  reordered_id = g_signal_connect_swapped (model, "rows_reordered",
                                           G_CALLBACK (model_changed),
                                           &stop);
+  changed_id = g_signal_connect_swapped (selection->tree_view, "notify::model",
+                                        G_CALLBACK (model_changed), 
+                                        &stop);
 
   /* find the node internally */
   path = gtk_tree_path_new_first ();
@@ -666,9 +670,8 @@ gtk_tree_selection_selected_foreach (GtkTreeSelection            *selection,
     {
       if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
         {
-          gtk_tree_model_get_iter (selection->tree_view->priv->model,
-                                   &iter, path);
-         (* func) (selection->tree_view->priv->model, path, &iter, data);
+          gtk_tree_model_get_iter (model, &iter, path);
+         (* func) (model, path, &iter, data);
         }
 
       if (stop)
@@ -721,20 +724,18 @@ out:
   if (path)
     gtk_tree_path_free (path);
 
-  g_signal_handler_disconnect (selection->tree_view->priv->model,
-                               inserted_id);
-  g_signal_handler_disconnect (selection->tree_view->priv->model,
-                               deleted_id);
-  g_signal_handler_disconnect (selection->tree_view->priv->model,
-                               reordered_id);
+  g_signal_handler_disconnect (model, inserted_id);
+  g_signal_handler_disconnect (model, deleted_id);
+  g_signal_handler_disconnect (model, reordered_id);
+  g_signal_handler_disconnect (selection->tree_view, changed_id);
+  g_object_unref (model);
 
   /* check if we have to spew a scary message */
   if (stop)
-    g_warning
-      ("The model has been modified from within gtk_tree_selection_selected_foreach.\n"
-       "This function is for observing the selections of the tree only.  If\n"
-       "you are trying to get all selected items from the tree, try using\n"
-       "gtk_tree_selection_get_selected_rows instead.\n");
+    g_warning ("The model has been modified from within gtk_tree_selection_selected_foreach.\n"
+              "This function is for observing the selections of the tree only.  If\n"
+              "you are trying to get all selected items from the tree, try using\n"
+              "gtk_tree_selection_get_selected_rows instead.\n");
 }
 
 /**
@@ -1482,7 +1483,14 @@ _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection,
     gtk_tree_path_free (anchor_path);
 
   if (dirty)
-    g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
+    g_signal_emit (selection, tree_selection_signals[CHANGED], 0);  
+}
+
+
+void 
+_gtk_tree_selection_emit_changed (GtkTreeSelection *selection)
+{
+  g_signal_emit (selection, tree_selection_signals[CHANGED], 0);  
 }
 
 /* NOTE: Any {un,}selection ever done _MUST_ be done through this function!
index fac7393a346aca81d6a300758412c3d3a33ab796..eca3f2c1885964978805322096e8b6c91a8b7377 100644 (file)
@@ -9507,7 +9507,6 @@ gtk_tree_view_set_model (GtkTreeView  *tree_view,
 
   tree_view->priv->model = model;
 
-
   if (tree_view->priv->model)
     {
       gint i;
@@ -9571,6 +9570,9 @@ gtk_tree_view_set_model (GtkTreeView  *tree_view,
 
   g_object_notify (G_OBJECT (tree_view), "model");
 
+  if (tree_view->priv->selection)
+  _gtk_tree_selection_emit_changed (tree_view->priv->selection);
+
   if (GTK_WIDGET_REALIZED (tree_view))
     gtk_widget_queue_resize (GTK_WIDGET (tree_view));
 }